package cn.wit.sst.ml.kmeans;

import java.util.List;

/**
 * 初始聚类中心选定策略：
	第一次选样本第一个点作为第一个初始聚类中心点Z1。
	第二个选距离第一个初始聚类中心点最远的点Z2。
	。。。
	第n个选距离前n-1个初始聚类点最远的点。
 *
 */
public class SimpleCenterStrategy implements CenterStrategy {
	private DistanceStrategy ds;

	public SimpleCenterStrategy(DistanceStrategy ds) {
		this.ds = ds;
	}

	@Override
	public Sample[] getCenters(List<Sample> samples, int k) {
		assert(samples != null && samples.size() > 0 && k > 0);

		System.out.println(samples);

		Sample[] centers = new Sample[k];

		// 第一个中心点取第一个样本点
		centers[0] = samples.get(0);

		// 第n个中心点取距离前n-1个中心点距离最大的样本点
		for (int i = 1; i < k; i++) {
			double max = 0;
			Sample fathest = null;
			for (Sample p : samples) {
				if (isCenterPoint(p, centers, i)) {
					continue;
				}

				// 获取当前样本点与前i个中心点的距离之和
				double total = getTotalDistance(p, centers, i);

				if (max < total) {
					max = total;
					fathest = p;
				}
			}

			assert(fathest != null);

			centers[i] = fathest;
		}

		return centers;
	}

	private boolean isCenterPoint(Sample p, Sample[] centers, int index) {
		for (int i = 0; i < index; i++) {
			if (centers[i] == p) {
				return true;
			}
		}

		return false;
	}

	private double getTotalDistance(Sample point, Sample[] centers, int k) {
		double sum = 0;
		for (int i = 0; i < k; i++) {
			double distance = ds.measure(point, centers[i]);
			sum += distance;
		}

		return sum;
	}
}
